package com.lijiajia.cloud.authserver.service.impl.mongodb;

import com.lijiajia.cloud.authserver.service.ClientService;
import com.lijiajia.cloud.common.core.pojo.CustomPage;
import com.lijiajia.cloud.authserver.pojo.mongodb.Client;
import com.lijiajia.cloud.authserver.pojo.request.ClientPageRequest;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

/**
 * 客户端服务 mongo实现
 *
 * @author lijiajia
 * @since 2019-4-28
 */
@Slf4j
@Service
public class MongoClientService implements ClientService {
	private final MongoTemplate mongoTemplate;
	private final PasswordEncoder clientPasswordEncoder;

	public MongoClientService(MongoTemplate mongoTemplate,
							  @Qualifier("clientPasswordEncoder") PasswordEncoder clientPasswordEncoder) {
		this.mongoTemplate = mongoTemplate;
		this.clientPasswordEncoder = clientPasswordEncoder;
	}

	@Override
	public boolean save(Client client) {
		assert client.getId() != null;
		Query query = new Query().addCriteria(Criteria.where(Client.ID).is(client.getId()));
		Update update = new Update();
		if (client.getAuthorizedGrantTypes() != null)
			update.set(Client.AUTHORIZED_GRANT_TYPES, client.getAuthorizedGrantTypes());
		if (client.getResourceIds() != null)
			update.set(Client.RESOURCE_IDS, client.getResourceIds());
		if (client.getScope() != null)
			update.set(Client.SCOPE, client.getScope());
		if (client.getAutoApproveScopes() != null)
			update.set(Client.AUTO_APPROVE_SCOPES, client.getAutoApproveScopes());
		if (client.getAuthorities() != null)
			update.set(Client.AUTHORITIES, client.getAuthorities());
		if (client.getRedirectUris() != null)
			update.set(Client.REDIRECT_URIS, client.getRedirectUris());
		if (client.getAccessTokenValiditySeconds() != null)
			update.set(Client.ACCESS_TOKEN_VALIDITY_SECONDS, client.getAccessTokenValiditySeconds());
		if (client.getRefreshTokenValiditySeconds() != null)
			update.set(Client.REFRESH_TOKEN_VALIDITY_SECONDS, client.getRefreshTokenValiditySeconds());
		if (client.getAdditionalInformation() != null)
			update.set(Client.ADDITIONAL_INFORMATION, client.getAdditionalInformation());
		UpdateResult result = mongoTemplate.updateFirst(query, update, Client.class);
		log.debug("clients update result:{}", result);
		return result.wasAcknowledged();
	}

	@Override
	public boolean deleteById(String id) {
		Query query = Query.query(Criteria.where(Client.ID).is(id));
		DeleteResult result = mongoTemplate.remove(query, Client.class);
		log.debug("clients deleted result:{}", result);
		return result.wasAcknowledged();
	}

	@Override
	public Optional<Client> findById(String id) {
		Query query = Query.query(Criteria.where(Client.ID).is(id));
		Client client = mongoTemplate.findOne(query, Client.class);
		return Optional.ofNullable(client);
	}

	@Override
	public List<Client> find() {
		Query query = new Query().with(Sort.by(Client.CREATED_DATE));
		return mongoTemplate.find(query, Client.class);
	}
}

